home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / games_d / rtanksrc.zip / NEWLOAD.C < prev    next >
Text File  |  1989-05-11  |  25KB  |  892 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dtypes.h>
  4. #include <string.h>
  5. #include <alloc.h>
  6. #include "code.h"
  7. #include "host.h"
  8. #include "newload.h"
  9. #include "callasm.h"
  10.  
  11. PSTR derror[] = {
  12.             "COMPILER ERROR",
  13.             "Symbol exists",
  14.             "Symbol table overflow",
  15.             "Symbol undefined",
  16.             "Syntax error",
  17.             "Symbol required as first argument",
  18.             "Label already used",
  19.             "Line reference not allowed as arg",
  20.             "Line reference required",
  21.             "Too few/many arguments supplied",
  22.             "Out of RAM",
  23.             ""
  24. };
  25.  
  26. #define _SYMUSED   1
  27. #define _VAROVER   2
  28. #define _UNDEF     3
  29. #define _SYNTAX    4
  30. #define _SYMREQ1   5
  31. #define _LABELUSED 6
  32. #define _NOLINE    7
  33. #define _LINEMUST  8
  34. #define _WRONGARGS 9
  35. #define _NORAM     10
  36.  
  37. p_RESOLVE  first_resolve;
  38. p_RESOLVE  last_resolve;
  39. p_RESOLVE  cresolve;
  40. p_LINER    lineref_start;
  41. p_LINER    lineref_end;
  42. p_LINE     lastline;
  43. p_LINE     cl;
  44. p_SYMB     first_symbol;
  45. p_SYMB     last_symbol;
  46. TANK       tanks[MAXPLAYERS];
  47. int        nplayers;
  48. int        lerror;
  49. BOOL       appendcl;
  50. int        num_symb;
  51. BOOL       bad_file;
  52. BOOL       noramleft;
  53. TOKEN      maketoken;
  54.  
  55. /*<f>----------------------------------------
  56.  * FUNCTION: <s> int n_compile_player(p_PLAYER p)
  57.  * PURPOSE : Compile a player and return the handle to it's structure
  58.  *         :
  59.  * CREATION: 01/06/1989 09:45:51
  60.  */
  61. int n_compile_player(p_PLAYER p)
  62. {
  63. int hand;
  64.  
  65.    noramleft=FALSE;
  66.  
  67.    hand=create_new_player(p->tankname);
  68.  
  69.    compile_program(&tanks[hand]);
  70.  
  71.    if (bad_file)
  72.       hand=-1;
  73.  
  74.    free_compiler_ram();
  75.  
  76. #ifdef DEBUG
  77.    list_program_structure(&tanks[hand]);
  78. #endif
  79.  
  80.    if (noramleft)
  81.       hand=-2;
  82.  
  83.    return hand;
  84. } /* int n_compile_player(p_PLAYER p) */
  85.  
  86. /*<f>----------------------------------------
  87.  * FUNCTION: <s> void init_structures(void)
  88.  * PURPOSE : Initilize all used data structures to known values
  89.  *         :
  90.  * CREATION: 12/14/1988 08:11:38
  91.  */
  92. void init_structures(void)
  93. {
  94.    nplayers=0;
  95. } /* void init_structures(void) */
  96.  
  97. /*<f>----------------------------------------
  98.  * FUNCTION: <s> int create_new_player(PSTR s)
  99.  * PURPOSE : Initilize a new players tank structure
  100.  *         :
  101.  * CREATION: 12/14/1988 08:12:43
  102.  */
  103. int create_new_player(PSTR s)
  104. {
  105.    if (nplayers==MAXPLAYERS)
  106.       return BAD;
  107.  
  108.    strcpy(tanks[nplayers].basefilename,s);
  109.    tanks[nplayers].prog=(0L);
  110.  
  111.    nplayers++;
  112.    return (nplayers-1);
  113. } /* int create_new_player(PSTR s) */
  114.  
  115. /*<f>----------------------------------------
  116.  * FUNCTION: <s> void compile_program(p_TANK t)
  117.  * PURPOSE : Load in tank logic program and compile it into
  118.  *         : interpreter usable code.
  119.  * CREATION: 12/14/1988 08:27:50
  120.  */
  121. void compile_program(p_TANK t)
  122. {
  123. char fn[60];
  124. FILE *fp;
  125. char ins[255], lcopy[255], *p;
  126. int pl,a;
  127. BOOL MakeNewLine;
  128. BOOL ferror, stopit;
  129. char err[50];
  130.  
  131.    strcpy(fn,t->basefilename);
  132.    strcat(fn,".TXT");
  133.  
  134.    if (!exist(fn)) {
  135.       bad_file=TRUE;
  136.       note_error("FILE NOT FOUND");
  137.    } else {
  138.       fp=fopen(fn,"rt");
  139.  
  140.       pl           = 0;
  141.       num_symb     = 0;
  142.       lastline     = 0L;
  143.       MakeNewLine  = TRUE;
  144.       ferror       = FALSE;
  145.       lineref_end  = lineref_start = NULL;
  146.       first_resolve= last_resolve  = NULL;
  147.       first_symbol = last_symbol   = NULL;
  148.  
  149.       create_token(&maketoken,"WHEREX");
  150.       add_symbol(&maketoken);
  151.       create_token(&maketoken,"WHEREY");
  152.       add_symbol(&maketoken);
  153.       create_token(&maketoken,"CGDIR");
  154.       add_symbol(&maketoken);
  155.       create_token(&maketoken,"CTDIR");
  156.       add_symbol(&maketoken);
  157.       create_token(&maketoken,"LOADED");
  158.       add_symbol(&maketoken);
  159.       create_token(&maketoken,"HIT");
  160.       add_symbol(&maketoken);
  161.       create_token(&maketoken,"NOMOVE");
  162.       add_symbol(&maketoken);
  163.       create_token(&maketoken,"TEAM");
  164.       add_symbol(&maketoken);
  165.       create_token(&maketoken,"MYTEAM");
  166.       add_symbol(&maketoken);
  167.       create_token(&maketoken,"BLOCKAGE");
  168.       add_symbol(&maketoken);
  169.       create_token(&maketoken,"MESSAGE");
  170.       add_symbol(&maketoken);
  171.  
  172.  
  173.       stopit=FALSE;
  174.  
  175.       while (fgets(ins,255,fp) && (!stopit)) {
  176.          pl++;
  177.          strcpy(lcopy,ins);
  178.          lcopy[strlen(lcopy)-1]=' ';
  179.  
  180.          /* Erase everything from a ";" onwards */
  181.          p=ins;
  182.          while ((*p)!=';' && (*p)) p++;
  183.          if ((*p)==';') (*p)=NULL;
  184.  
  185.          lerror=0;
  186.  
  187.          if (MakeNewLine) {
  188. #ifdef DEBUG
  189.             printf("-> Creating newline for line %s\n",lcopy);
  190. #endif
  191.             cl=create_newline();
  192.             nuke_line_contents(cl);
  193.          }
  194.  
  195.          cl->pline=pl;
  196.          appendcl=TRUE;
  197.  
  198.          parse_line(ins);
  199.  
  200.          switch (lerror) {
  201.             case 0   : /* No errors in this line, add it to array if required */
  202.                        if (appendcl) {
  203.                           add_line(t,cl);
  204.                           MakeNewLine=TRUE;
  205.                        } else MakeNewLine=FALSE;
  206.                        break;
  207.  
  208.             default  : sprintf(err,"%s L%d",derror[lerror],pl);
  209.                        note_error(err);
  210.                        sprintf(err,"- %s",lcopy);
  211.                        note_error(err);
  212.  
  213.                        ferror=TRUE;
  214.                        MakeNewLine=FALSE;
  215.                        if (lerror==_NORAM) {
  216.                           stopit=TRUE;
  217.                           noramleft=TRUE;
  218.                        }
  219.                        break;
  220.          }
  221.       }
  222.  
  223.       fclose(fp);
  224.  
  225.       bad_file=FALSE;
  226.       if (!ferror)
  227.          resolve_references(t);
  228.       else
  229.          bad_file=TRUE;
  230.    }
  231. } /* void compile_program(p_TANK t) */
  232.  
  233. /*<f>----------------------------------------
  234.  * FUNCTION: <s> BOOL exist(PSTR s)
  235.  * PURPOSE : Returns TRUE is file exists, FALSE otherwise
  236.  *         :
  237.  * CREATION: 12/14/1988 08:49:28
  238.  */
  239. BOOL exist(PSTR s)
  240. {
  241. FILE *fp;
  242.  
  243.    if ((fp=fopen(s,"rt"))==NULL) return FALSE;
  244.  
  245.    fclose(fp);
  246.    return TRUE;
  247. } /* BOOL exist(PSTR s) */
  248.  
  249. /*<f>----------------------------------------
  250.  * FUNCTION: <s> void nuke_line_contents(p_LINE l)
  251.  * PURPOSE : Clear out a line structure to a known value
  252.  *         :
  253.  * CREATION: 12/14/1988 08:57:29
  254.  */
  255. void nuke_line_contents(p_LINE l)
  256. {
  257.    l->pline=BAD;
  258.    l->command=BAD;
  259.  
  260.    nuke_argument(&l->arg1);
  261.    nuke_argument(&l->arg2);
  262.    nuke_argument(&l->arg3);
  263.    nuke_argument(&l->arg4);
  264.  
  265. } /* void nuke_line_contents(p_LINE l) */
  266.  
  267. /*<f>----------------------------------------
  268.  * FUNCTION: <s> void nuke_argument(p_ARG a)
  269.  * PURPOSE : Clear out a argument structure to a known value
  270.  *         :
  271.  * CREATION: 12/14/1988 08:59:29
  272.  */
  273. void nuke_argument(p_ARG a)
  274. {
  275.    a->atype=BAD;
  276.    a->value=BAD;
  277.    a->linedest=NULL;
  278. } /* void nuke_argument(p_ARG a) */
  279.  
  280. /*<f>----------------------------------------
  281.  * FUNCTION: <s> void parse_line(PSTR l)
  282.  * PURPOSE : Parse out a text line into structure elements
  283.  *         :
  284.  * CREATION: 12/14/1988 09:03:38
  285.  */
  286. void parse_line(PSTR l)
  287. {
  288. TOKEN t[MAXTOKENS];
  289. PSTR  p;
  290. int   nt;
  291.  
  292.    strupr(l);   /* Make everything UPPER-CASE */
  293.  
  294.    memset(t,0,sizeof(t));
  295.  
  296.    p=strtok(l," ,\n\t");
  297.    nt=0;
  298.  
  299.    while (nt<MAXTOKENS && p!=NULL) {
  300.       strcpy(t[nt++].token,p);
  301.       p = strtok(NULL," ,\n\t");
  302.    }
  303.  
  304.    if (nt>0)
  305.       fill_structure(t,nt-1);
  306.    else {
  307.       lerror=0;
  308.       appendcl=FALSE;
  309.    }
  310. } /* void parse_line(PSTR l) */
  311.  
  312. /*<f>----------------------------------------
  313.  * FUNCTION: <s> void fill_structure(TOKEN t[], int nt)
  314.  * PURPOSE : Fill Current Line structure (CL) with
  315.  *         : information from supplied token list
  316.  * CREATION: 12/14/1988 09:20:01
  317.  */
  318. void fill_structure(TOKEN t[], int nt)
  319. {
  320. int cmd, na;
  321.  
  322.    if (t[0].token[0]==':') {
  323.       add_lineref(&t[0]);
  324.       appendcl=FALSE;
  325.       return;
  326.    }
  327.  
  328.    cmd=BAD;
  329.    if (strcmp(t[0].token,"MAKE"   )==0) { cmd=_MAKE   ; na=1; }
  330.    if (strcmp(t[0].token,"AUTO"   )==0) { cmd=_AUTO   ; na=1; }
  331.    if (strcmp(t[0].token,"LOCK"   )==0) { cmd=_LOCK   ; na=1; }
  332.    if (strcmp(t[0].token,"CHANNEL")==0) { cmd=_CHANNEL; na=1; }
  333.    if (strcmp(t[0].token,"TX"     )==0) { cmd=_TX     ; na=3; }
  334.    if (strcmp(t[0].token,"RX"     )==0) { cmd=_RX     ; na=3; }
  335.    if (strcmp(t[0].token,"CONV"   )==0) { cmd=_CONV   ; na=3; }
  336.    if (strcmp(t[0].token,"JAMMER" )==0) { cmd=_JAMMER ; na=1; }
  337.    if (strcmp(t[0].token,"RADAR"  )==0) { cmd=_RADAR  ; na=1; }
  338.    if (strcmp(t[0].token,"SCAN"   )==0) { cmd=_SCAN   ; na=2; }
  339.    if (strcmp(t[0].token,"FACE"   )==0) { cmd=_FACE   ; na=1; }
  340.    if (strcmp(t[0].token,"AIM"    )==0) { cmd=_AIM    ; na=1; }
  341.    if (strcmp(t[0].token,"SELECT" )==0) { cmd=_SELECT ; na=1; }
  342.    if (strcmp(t[0].token,"SCOPE"  )==0) { cmd=_SCOPE  ; na=1; }
  343.    if (strcmp(t[0].token,"JEQ"    )==0) { cmd=_JEQ    ; na=3; }
  344.    if (strcmp(t[0].token,"JLT"    )==0) { cmd=_JLT    ; na=3; }
  345.    if (strcmp(t[0].token,"JNEQ"   )==0) { cmd=_JNEQ   ; na=3; }
  346.    if (strcmp(t[0].token,"JGT"    )==0) { cmd=_JGT    ; na=3; }
  347.    if (strcmp(t[0].token,"LEFT"   )==0) { cmd=_LEFT   ; na=0; }
  348.    if (strcmp(t[0].token,"RIGHT"  )==0) { cmd=_RIGHT  ; na=0; }
  349.    if (strcmp(t[0].token,"GLEFT"  )==0) { cmd=_GLEFT  ; na=0; }
  350.    if (strcmp(t[0].token,"GRIGHT" )==0) { cmd=_GRIGHT ; na=0; }
  351.    if (strcmp(t[0].token,"SET"    )==0) { cmd=_SET    ; na=2; }
  352.    if (strcmp(t[0].token,"ADD"    )==0) { cmd=_ADD    ; na=2; }
  353.    if (strcmp(t[0].token,"RAND"   )==0) { cmd=_RAND   ; na=2; }
  354.    if (strcmp(t[0].token,"MOVE"   )==0) { cmd=_MOVE   ; na=0; }
  355.    if (strcmp(t[0].token,"GOTO"   )==0) { cmd=_GOTO   ; na=1; }
  356.    if (strcmp(t[0].token,"FIRE"   )==0) { cmd=_FIRE   ; na=0; }
  357.    if (strcmp(t[0].token,"CALL"   )==0) { cmd=_CALL   ; na=1; }
  358.    if (strcmp(t[0].token,"RETURN" )==0) { cmd=_RETURN ; na=0; }
  359.  
  360.    if (cmd==BAD) {
  361.       lerror=_SYNTAX;
  362.       return;
  363.    }
  364.  
  365.    if (na!=nt) {
  366.       lerror=_WRONGARGS;
  367.       return;
  368.    }
  369.  
  370.    if (cmd==_MAKE) {
  371.       add_symbol(&t[1]);
  372.       appendcl=FALSE;
  373.       return;
  374.    }
  375.  
  376.    cl->command=cmd;
  377.  
  378.    switch (cmd) {
  379.       case   _SCOPE  :
  380.       case   _RADAR  : fill_s(&t[1]);               break;
  381.  
  382.       case   _SET    :
  383.       case   _ADD    :
  384.       case   _RAND   :
  385.       case   _SCAN   : fill_sa(&t[1],&t[2]);        break;
  386.  
  387.       case   _AUTO   :
  388.       case   _LOCK   :
  389.       case   _JAMMER :
  390.       case   _CHANNEL:
  391.       case   _FACE   :
  392.       case   _AIM    :
  393.       case   _SELECT : fill_a(&t[1]);               break;
  394.  
  395.       case   _JLT    :
  396.       case   _JNEQ   :
  397.       case   _JGT    :
  398.       case   _JEQ    : fill_aal(&t[1],&t[2],&t[3]); break;
  399.  
  400.       case   _TX     : fill_aaa(&t[1],&t[2],&t[3]); break;
  401.  
  402.       case   _RX     : fill_sss(&t[1],&t[2],&t[3]); break;
  403.  
  404.       case   _CONV   : fill_aas(&t[1],&t[2],&t[3]); break;
  405.  
  406.       case   _GOTO   :
  407.       case   _CALL   : fill_l(&t[1]);               break;
  408.    }
  409.  
  410. } /* void fill_structure(TOKEN t[], int nt) */
  411.  
  412. /*<f>----------------------------------------
  413.  * FUNCTION: <s> void fill_l(p_TOKEN t1)
  414.  * PURPOSE : Fill Current Line structure with a LINEREF command
  415.  *         :
  416.  * CREATION: 12/15/1988 10:27:49
  417.  */
  418. void fill_l(p_TOKEN t1)
  419. {
  420.    if (!parse_arg(&cl->arg1, t1))
  421.       lerror=_SYNTAX;
  422.    else if (cl->arg1.atype!=LINEREF)
  423.       lerror=_LINEMUST;
  424. } /* void fill_l(p_TOKEN t1) */
  425.  
  426. /*<f>----------------------------------------
  427.  * FUNCTION: <s> void fill_sa(p_TOKEN t1,p_TOKEN t2)
  428.  * PURPOSE : Fill CL structure with SYMBOL,ANYTHING command
  429.  *         :
  430.  * CREATION: 12/15/1988 10:31:35
  431.  */
  432. void fill_sa(p_TOKEN t1,p_TOKEN t2)
  433. {
  434.    if (!parse_arg(&cl->arg1, t1) || !parse_arg(&cl->arg2, t2))
  435.       lerror=_SYNTAX;
  436.    else if (cl->arg1.atype!=SYMBOL)
  437.       lerror=_SYMREQ1;
  438.    else if (cl->arg2.atype==LINEREF)
  439.       lerror=_NOLINE;
  440. } /* void fill_sa(p_TOKEN t1,p_TOKEN t2) */
  441.  
  442. /*-------------------------------------
  443.  * Function : void fill_sss(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3)
  444.  * Purpose  : Fill CL structure with SYMBOL, SYMBOL, SYMBOL command
  445.  * Date     : 02/13/1989 22:28:53
  446.  */
  447. void fill_sss(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3)
  448. {
  449.    if (!parse_arg(&cl->arg1, t1) ||
  450.        !parse_arg(&cl->arg2, t2) ||
  451.        !parse_arg(&cl->arg3, t3))
  452.           lerror=_SYNTAX;
  453.    else if (cl->arg1.atype!=SYMBOL || cl->arg2.atype!=SYMBOL || cl->arg3.atype!=SYMBOL)
  454.       lerror=_SYMREQ1;
  455. } /* void fill_sss(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3) */
  456.  
  457. /*-------------------------------------
  458.  * Function : void fill_aas(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3)
  459.  * Purpose  : Fill CL structure with ANYTHING, ANYTHING, SYMBOL command
  460.  * Date     : 02/13/1989 22:28:53
  461.  */
  462. void fill_aas(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3)
  463. {
  464.    if (!parse_arg(&cl->arg1, t1) ||
  465.        !parse_arg(&cl->arg2, t2) ||
  466.        !parse_arg(&cl->arg3, t3))
  467.           lerror=_SYNTAX;
  468.    else if (cl->arg1.atype==LINEREF || cl->arg2.atype==LINEREF)
  469.         lerror = _NOLINE;
  470.    else if (cl->arg3.atype!=SYMBOL)
  471.       lerror=_SYMREQ1;
  472. } /* void fill_aas(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3) */
  473.  
  474. /*-------------------------------------
  475.  * Function : void fill_aaa(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3)
  476.  * Purpose  : Fill CL structure with ANYTHING, ANYTHING, ANYTHING command
  477.  * Date     : 02/13/1989 22:32:18
  478.  */
  479. void fill_aaa(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3)
  480. {
  481.    if (!parse_arg(&cl->arg1, t1) ||
  482.        !parse_arg(&cl->arg2, t2) ||
  483.        !parse_arg(&cl->arg3, t3))
  484.           lerror=_SYNTAX;
  485.    else if (cl->arg1.atype==LINEREF || cl->arg2.atype==LINEREF || cl->arg3.atype==LINEREF)
  486.       lerror=_NOLINE;
  487.  
  488. } /* void fill_aaa(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3) */
  489.  
  490. /*<f>----------------------------------------
  491.  * FUNCTION: <s> void fill_aal(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3)
  492.  * PURPOSE : Fill CL structure with ANYTHING, ANYTHING, LINEREF command
  493.  *         :
  494.  * CREATION: 12/15/1988 10:34:46
  495.  */
  496. void fill_aal(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3)
  497. {
  498.    if (!parse_arg(&cl->arg1, t1) ||
  499.        !parse_arg(&cl->arg2, t2) ||
  500.        !parse_arg(&cl->arg3, t3))
  501.           lerror=_SYNTAX;
  502.    else if (cl->arg1.atype==LINEREF || cl->arg2.atype==LINEREF)
  503.       lerror=_NOLINE;
  504.    else if (cl->arg3.atype!=LINEREF)
  505.       lerror=LINEREF;
  506. } /* void fill_aal(p_TOKEN t1, p_TOKEN t2, p_TOKEN t3) */
  507.  
  508. /*<f>----------------------------------------
  509.  * FUNCTION: <s> void fill_a(p_TOKEN t1)
  510.  * PURPOSE : Fill CL structure with ANYTHING command
  511.  *         :
  512.  * CREATION: 12/15/1988 10:38:19
  513.  */
  514. void fill_a(p_TOKEN t1)
  515. {
  516.    if (!parse_arg(&cl->arg1,t1))
  517.       lerror=_SYNTAX;
  518.    else if (cl->arg1.atype==LINEREF)
  519.       lerror=_NOLINE;
  520. } /* void fill_a(p_TOKEN t1) */
  521.  
  522. /*<f>----------------------------------------
  523.  * FUNCTION: <s> void fill_s(p_TOKEN t1)
  524.  * PURPOSE : Fill CL structure with SYMBOL command
  525.  *         :
  526.  * CREATION: 12/15/1988 10:39:29
  527.  */
  528. void fill_s(p_TOKEN t1)
  529. {
  530.    if (!parse_arg(&cl->arg1,t1))
  531.       lerror=_SYNTAX;
  532.    else if (cl->arg1.atype!=SYMBOL)
  533.       lerror=_SYMREQ1;
  534. } /* void fill_s(p_TOKEN t1) */
  535.  
  536. /*<f>----------------------------------------
  537.  * FUNCTION: <s> BOOL parse_arg(p_ARG a, p_TOKEN t)
  538.  * PURPOSE : Parse out token T into argument A
  539.  *         :
  540.  * CREATION: 12/15/1988 10:42:03
  541.  */
  542. BOOL parse_arg(p_ARG a, p_TOKEN t)
  543. {
  544.    if (!t->token) return FALSE;
  545.  
  546.    if (t->token[0]==':') {
  547.       a->atype=LINEREF;
  548.       if ((a->linedest=find_lineref(t))==NULL)
  549.          add_resolve(t);
  550.       return TRUE;
  551.    } else if ((t->token[0]=='-') || (t->token[0]>='0' && t->token[0]<='9')) {
  552.       a->atype=CONSTANT;
  553.       a->value=atoi(t->token);
  554.       return TRUE;
  555.    }
  556.    a->atype=SYMBOL;
  557.    a->value=find_symbol(t);
  558.    return (a->value==BAD) ? FALSE : TRUE;
  559. } /* BOOL parse_arg(p_ARG a, p_TOKEN t) */
  560.  
  561. /*-------------------------------------
  562.  * Function : void add_lineref(p_TOKEN t)
  563.  * Purpose  : Add's a new line reference from token T
  564.  * Date     : 12/15/1988 14:19:38
  565.  */
  566. void add_lineref(p_TOKEN t)
  567. {
  568. p_LINER newliner;
  569.  
  570.    newliner=(p_LINER) malloc(sizeof(LINER));
  571.  
  572.    if (newliner==NULL) {
  573.       lerror=_NORAM;
  574.       return;
  575.    }
  576.  
  577.    newliner->next_liner=NULL;
  578.    newliner->lineref  =cl;
  579.    strcpy(newliner->lsymbol.token,t->token);
  580.  
  581.    if (lineref_end==NULL)
  582.       lineref_start=newliner;
  583.    else lineref_end->next_liner=newliner;
  584.  
  585.    lineref_end=newliner;
  586.  
  587. } /* void add_lineref(p_TOKEN t) */
  588.  
  589. /*-------------------------------------
  590.  * Function : p_LINE find_lineref(p_TOKEN t)
  591.  * Purpose  : Search line reference file for token T and return pointer to line
  592.  * Date     : 12/15/1988 14:44:37
  593.  */
  594. p_LINE find_lineref(p_TOKEN t)
  595. {
  596. p_LINER rec;
  597.  
  598.    for (rec=lineref_start; rec!=NULL; rec=rec->next_liner)
  599.        if (strcmp(rec->lsymbol.token,t->token)==0)
  600.           return rec->lineref;
  601.  
  602.    return (0L);
  603.  
  604. } /* p_LINE find_lineref(p_TOKEN t) */
  605.  
  606. /*-------------------------------------
  607.  * Function : int find_symbol(p_TOKEN t);
  608.  * Purpose  : Search symbol table for token T
  609.  * Date     : 12/15/1988 15:22:56
  610.  */
  611. int find_symbol(p_TOKEN t)
  612. {
  613. p_SYMB rec;
  614.  
  615.    for (rec=first_symbol; rec!=NULL; rec=rec->next_symbol)
  616.        if (strcmp(rec->symbol.token,t->token)==0)
  617.           return rec->memloc;
  618.  
  619.    return BAD;
  620.  
  621. } /* int find_symbol(p_TOKEN t); */
  622.  
  623. /*-------------------------------------
  624.  * Function : void add_line(p_TANK t, p_LINE l)
  625.  * Purpose  : Adds new line L to tank structure T
  626.  * Date     : 12/15/1988 14:22:24
  627.  */
  628. void add_line(p_TANK t, p_LINE l)
  629. {
  630.    l->nextline=(0L);
  631.  
  632.    if (lastline==(0L))
  633.       t->prog=l;
  634.    else lastline->nextline=l;
  635.  
  636.    lastline=l;
  637. } /* void add_line(p_TANK t, p_LINE l) */
  638.  
  639. /*-------------------------------------
  640.  * Function : p_LINE create_newline(void)
  641.  * Purpose  : Gets ram for a new line structure
  642.  * Date     : 12/15/1988 14:30:20
  643.  */
  644. p_LINE create_newline(void)
  645. {
  646. p_LINE newline;
  647.  
  648.    newline=(p_LINE) farmalloc(sizeof(LINE));
  649.    if (newline==(0L))
  650.       lerror=_NORAM;
  651.    return newline;
  652. } /* p_LINE create_newline(void) */
  653.  
  654. /*-------------------------------------
  655.  * Function : void add_resolve(p_TOKEN t)
  656.  * Purpose  : Add a new lineref to resolve later
  657.  * Date     : 12/15/1988 14:52:52
  658.  */
  659. void add_resolve(p_TOKEN t)
  660. {
  661. p_RESOLVE newres;
  662.  
  663.    newres=(p_RESOLVE) malloc(sizeof(RESOLVE));
  664.    if (newres==NULL) {
  665.       lerror=_NORAM;
  666.       return;
  667.    }
  668.  
  669.    newres->next_resolve=NULL;
  670.    strcpy(newres->lineref.token,t->token);
  671.  
  672.    if (last_resolve==NULL)
  673.       first_resolve=newres;
  674.    else last_resolve->next_resolve=newres;
  675.  
  676.    last_resolve=newres;
  677.  
  678. } /* void add_resolve(p_TOKEN t) */
  679.  
  680. /*-------------------------------------
  681.  * Function : void add_symbol(p_TOKEN t)
  682.  * Purpose  : Add's new symbol to symbol table
  683.  * Date     : 12/15/1988 15:15:50
  684.  */
  685. void add_symbol(p_TOKEN t)
  686. {
  687. p_SYMB news;
  688.  
  689.    news=(p_SYMB) malloc(sizeof(SYMB));
  690.    if (news==NULL) {
  691.       lerror=_NORAM;
  692.       return;
  693.    }
  694.  
  695.    news->next_symbol=NULL;
  696.    strcpy(news->symbol.token,t->token);
  697.    news->memloc = num_symb++;
  698.  
  699.    if (last_symbol==NULL)
  700.       first_symbol=news;
  701.    else last_symbol->next_symbol=news;
  702.  
  703.    last_symbol=news;
  704. } /* void add_symbol(p_TOKEN t) */
  705.  
  706. /*-------------------------------------
  707.  * Function : void list_symbol_table(void)
  708.  * Purpose  : List symbol table to screen for debugging
  709.  * Date     : 12/15/1988 15:59:00
  710.  */
  711. void list_symbol_table(void)
  712. {
  713. p_SYMB rec;
  714.  
  715.    printf("\n-----------------\nSYMBOLS DEFINED\n\n");
  716.  
  717.    for (rec=first_symbol; rec!=NULL; rec=rec->next_symbol)
  718.        printf("SYMBOL : %s \n",rec->symbol.token);
  719.  
  720. } /* void list_symbol_table(void) */
  721.  
  722. /*-------------------------------------
  723.  * Function : void resolve_references(p_TANK t)
  724.  * Purpose  : Index undefined line references to correct line, if any
  725.  * Date     : 12/15/1988 16:20:36
  726.  */
  727. void resolve_references(p_TANK t)
  728. {
  729. p_LINE rec;
  730.  
  731.    cresolve=first_resolve;
  732.  
  733.    for (rec=t->prog; rec!=NULL; rec=rec->nextline) {
  734.        check_link(&rec->arg1, rec->pline);
  735.        check_link(&rec->arg2, rec->pline);
  736.        check_link(&rec->arg3, rec->pline);
  737.    }
  738. } /* void resolve_references(p_TANK t) */
  739.  
  740. /*-------------------------------------
  741.  * Function : void check_link(p_ARG a, int pl)
  742.  * Purpose  : Check if an argument is resolved, do so if not
  743.  * Date     : 12/15/1988 16:24:48
  744.  */
  745. void check_link(p_ARG a, int pl)
  746. {
  747. char buf[100];
  748.    if (a->atype!=LINEREF || a->linedest!=NULL)
  749.       return;
  750.  
  751.    a->linedest=find_lineref(&cresolve->lineref);
  752.  
  753.    if (a->linedest==NULL) {
  754.       sprintf(buf,"Undefined line reference \"%s\" in line %d\n\r",cresolve->lineref.token,pl);
  755.       note_error(buf);
  756.       bad_file=TRUE;
  757.    }
  758.  
  759.    if (cresolve->next_resolve!=NULL)
  760.       cresolve=cresolve->next_resolve;
  761.  
  762. } /* void check_link(p_ARG a, int pl) */
  763.  
  764. /*-------------------------------------
  765.  * Function : void free_compiler_ram(void)
  766.  * Purpose  : Free up symbol table and resolve table ram
  767.  * Date     : 12/15/1988 16:49:35
  768.  */
  769. void free_compiler_ram(void)
  770. {
  771. p_RESOLVE res;
  772. p_RESOLVE tres;
  773.  
  774. p_SYMB    sym;
  775. p_SYMB    tsym;
  776.  
  777.    res=first_resolve;
  778.    while (res!=NULL) {
  779.       tres=res;
  780.       res=res->next_resolve;
  781.       free(tres);
  782.    }
  783.    first_resolve=NULL;
  784.  
  785.    sym=first_symbol;
  786.    while (sym!=NULL) {
  787.       tsym=sym;
  788.       sym=sym->next_symbol;
  789.       free(tsym);
  790.    }
  791.    first_symbol=NULL;
  792.  
  793. } /* void free_compiler_ram(void) */
  794.  
  795. /*<f>----------------------------------------
  796.  * FUNCTION: <s> void list_program_structure(p_TANK t)
  797.  * PURPOSE : List program structure
  798.  *         :
  799.  * CREATION: 01/08/1989 14:22:23
  800.  */
  801. void list_program_structure(p_TANK t)
  802. {
  803. p_LINE rec;
  804.  
  805.    rec=t->prog;
  806.  
  807.    while (rec!=(0L)) {
  808.       explain_line(rec);
  809.       printf("\n");
  810.       rec=rec->nextline;
  811.    }
  812. } /* void list_program_structure(p_TANK t) */
  813.  
  814. /*<f>----------------------------------------
  815.  * FUNCTION: <s> void explain_line(p_LINE l)
  816.  * PURPOSE : What does line L contain
  817.  *         :
  818.  * CREATION: 01/08/1989 15:08:56
  819.  */
  820. void explain_line(p_LINE l)
  821. {
  822. char cmd[20];
  823.  
  824.       switch(l->command) {
  825.          case BAD     : strcpy(cmd,"BAD"); break;
  826.          case _LEFT   : strcpy(cmd,"LEFT"); break;
  827.          case _JLT    : strcpy(cmd,"JLT"); break;
  828.          case _JGT    : strcpy(cmd,"JGT"); break;
  829.          case _GOTO   : strcpy(cmd,"GOTO"); break;
  830.          case _JEQ    : strcpy(cmd,"JEQ"); break;
  831.          case _JNEQ   : strcpy(cmd,"JNEQ"); break;
  832.          case _CALL   : strcpy(cmd,"CALL"); break;
  833.          case _MOVE   : strcpy(cmd,"MOVE"); break;
  834.          case _GLEFT  : strcpy(cmd,"GLEFT"); break;
  835.          case _FIRE   : strcpy(cmd,"FIRE"); break;
  836.          case _RETURN : strcpy(cmd,"RETURN"); break;
  837.          case _SET    : strcpy(cmd,"SET"); break;
  838.          case _ADD    : strcpy(cmd,"ADD"); break;
  839.          case _RAND   : strcpy(cmd,"RAND"); break;
  840.          case _RIGHT  : strcpy(cmd,"RIGHT"); break;
  841.          case _GRIGHT : strcpy(cmd,"GRIGHT"); break;
  842.          case _SELECT : strcpy(cmd,"SELECT"); break;
  843.          case _RADAR  : strcpy(cmd,"RADAR"); break;
  844.          case _SCAN   : strcpy(cmd,"SCAN"); break;
  845.          case _MAKE   : strcpy(cmd,"MAKE"); break;
  846.       }
  847.  
  848.       printf("[%2d. %s] ",l->pline,cmd);
  849.  
  850.       explain_arg(&l->arg1);
  851.       explain_arg(&l->arg2);
  852.       explain_arg(&l->arg3);
  853.  
  854. } /* void explain_line(p_LINE l) */
  855.  
  856. /*<f>----------------------------------------
  857.  * FUNCTION: <s> void explain_arg(p_ARG a)
  858.  * PURPOSE : Explain what arg A does or contains
  859.  *         :
  860.  * CREATION: 01/08/1989 15:12:13
  861.  */
  862. void explain_arg(p_ARG a)
  863. {
  864.    switch(a->atype) {
  865.       case CONSTANT : printf("[%d] ",a->value);  break;
  866.       case SYMBOL   : printf("<%d> ",a->value);  break;
  867.       case LINEREF  : explain_line(a->linedest); break;
  868.       case BAD      : printf(" * "); break;
  869.    }
  870. } /* void explain_arg(p_ARG a) */
  871.  
  872. /*<f>----------------------------------------
  873.  * FUNCTION: <s> p_TANK get_tank_pointer(int n)
  874.  * PURPOSE : Returns pointer to tank structure N
  875.  *         :
  876.  * CREATION: 01/09/1989 06:51:41
  877.  */
  878. p_TANK get_tank_pointer(int n)
  879. {
  880.    return (&tanks[n]);
  881. } /* p_TANK get_tank_pointer(int n) */
  882.  
  883. /*<f>----------------------------------------
  884.  * FUNCTION: <s> void create_token(p_TOKEN t, PSTR s)
  885.  * PURPOSE : Create a token T from string s
  886.  *         :
  887.  * CREATION: 01/12/1989 08:06:13
  888.  */
  889. void create_token(p_TOKEN t, PSTR s)
  890. {
  891.    strcpy(t->token,s);
  892. } /* void create_token(p_TOKEN t, PSTR s) */